﻿using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
[CustomEditor(typeof(ApplyNormalMapToMesh))]
public class ApplyNormalMapToMeshEditor : Editor
{
    public override void OnInspectorGUI()
    {
        var o = (ApplyNormalMapToMesh)target;
        base.OnInspectorGUI();
        if (GUILayout.Button("Import"))
        {
            o.Import();
        }
        if (GUILayout.Button("ResetNormal"))
        {
            o.ResetNormal();
        }
        if (GUILayout.Button("Start(Back up Mesh & Normals)"))
        {
            o.Start();
        }
    }
}
#endif
public class ApplyNormalMapToMesh : MonoBehaviour
{
    public Texture2D tex2d;
    public int texSize = 1024;
    private SkinnedMeshRenderer smr;
    private Mesh mesh;
    private Vector3[] normals;
    private Vector3[] originNormals;
    private Vector2[] uvs;
    private Color[] colors;
    public bool inverseX = true;
    public bool inverseY;
    public bool inverseRGB;
    public void ResetNormal()
    {
        mesh.normals = originNormals;
        mesh.RecalculateTangents();
    }
    public void ImportFromColors()
    {
        var nl = new List<Vector3>();
        int i = 0;
        foreach (var uv in uvs)
        {
            var p = uv * texSize;
            var color = colors[i];
            Vector3 n = inverseRGB ?
                new Vector3(color.b, color.g, color.r) :
                new Vector3(color.r, color.g, color.b);
            n = n.normalized;
            nl.Add(n);
            i++;
        }
        mesh.normals = nl.ToArray();
        mesh.RecalculateTangents();
    }
    public void Import()
    {
        var nl = new List<Vector3>();
        foreach (var uv in uvs)
        {
            var p = uv * texSize;
            var color = tex2d.GetPixel(
                inverseX ? texSize - Mathf.RoundToInt(p.x) : Mathf.RoundToInt(p.x),
                inverseY ? texSize - Mathf.RoundToInt(p.y) : Mathf.RoundToInt(p.y));
            Vector3 n = inverseRGB ?
                new Vector3(color.b, color.g, color.r) :
                new Vector3(color.r, color.g, color.b);
            n = n.normalized;
            nl.Add(n);
        }
        mesh.normals = nl.ToArray();
        mesh.RecalculateTangents();
    }
    public void Start()
    {
        smr = GetComponent<SkinnedMeshRenderer>();
        mesh = Instantiate(smr.sharedMesh);
        smr.sharedMesh = mesh;
        originNormals = mesh.normals;
        normals = mesh.normals;
        uvs = mesh.uv;
        colors = mesh.colors;
    }
}
